import newArrayProto from "./array";
import Dep from "./dep";
class Observer {
    constructor(data) {
        this.dep = new Dep()
        Object.defineProperty(data, '__ob__', {
            value: this,
            enumerable: false,// __ob__ 此属性不可被循环遍历
        })
        if (Array.isArray(data)) {
            data.__proto__ = newArrayProto
            return this.observerArray(data)
        }
        this.walk(data)


    }

    observerArray = function (data) {
        data.forEach((item) => observer(item))
    }

    walk = function (data) {
        Object.keys(data).forEach(key => defineReactive(data, key, data[key]))
    }
}


function deepDependArray(value) {
    for (let i = 0; i < value.length; i++) {
        let item = value[i]
        if (item.__ob__) {
            item.__ob__.dep.depend()
        }
        if (Array.isArray(item)) {
            deepDependArray(item)
        }
    }

}
export function defineReactive(target, key, value) {

    let childDep = observer(value)?.dep
    let dep = new Dep()
    Object.defineProperty(target, key, {

        get: function () {
            if (Dep.target) { // 在渲染时会取值 此时Dep.target为当前的watcher
                dep.depend()  // 将 watcher 添加道此属性的dep中
                if (childDep) {
                    if (Array.isArray(value)) {
                        deepDependArray(value)
                    }

                }
            }
            return value
        },
        set: function (newValue) {
            if (newValue === value) return
            observer(newValue)
            value = newValue
            dep.notify()
        },
    })

}



export default function observer(data) {

    if (typeof data !== 'object' || data == null) return

    return new Observer(data)
}